from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required
from app.models.work_order import WorkOrderField, WorkOrderFieldValue
from app.models import db
from .work_orders_utils import get_current_user, handle_db_error
from app.utils.auth import require_permission
import json
import traceback

work_orders_fields_bp = Blueprint('work_orders_fields', __name__)

@work_orders_fields_bp.route('/fields', methods=['GET'])
@jwt_required()
@require_permission('work_order.view')
def get_work_order_fields():
    """获取工单字段列表（包括基础字段和自定义字段）"""
    try:
        # 获取查询参数
        is_active = request.args.get('is_active')
        field_category = request.args.get('field_category')  # basic, custom, all
        
        # 构建查询
        query = WorkOrderField.query
        
        if is_active is not None:
            is_active_bool = is_active.lower() in ['true', '1', 'yes']
            query = query.filter(WorkOrderField.is_active == is_active_bool)
        
        if field_category and field_category != 'all':
            query = query.filter(WorkOrderField.field_category == field_category)
        
        # 按排序顺序获取字段
        fields = query.order_by(WorkOrderField.sort_order, WorkOrderField.id).all()
        
        return jsonify({
            'fields': [field.to_dict() for field in fields]
        }), 200

    except Exception as e:
        return jsonify({'error': str(e)}), 500

@work_orders_fields_bp.route('/fields', methods=['POST'])
@jwt_required()
@require_permission('work_order.field_manage')
@handle_db_error("创建工单字段")
def create_work_order_field():
    """创建工单自定义字段"""
    data = request.get_json()

    if not data.get('name'):
        return jsonify({'error': '字段名称不能为空'}), 400

    # 自动生成标签，如果未提供
    label = data.get('label') if data.get('label') else data['name']

    # 检查字段名是否已存在
    if WorkOrderField.query.filter_by(name=data['name']).first():
        return jsonify({'error': '字段名称已存在'}), 400

    # 验证字段类型
    valid_types = ['text', 'textarea', 'number', 'date', 'datetime', 'select', 'radio', 'checkbox', 'file']
    field_type = data.get('field_type', 'text')
    if field_type not in valid_types:
        return jsonify({'error': f'无效的字段类型，支持的类型：{valid_types}'}), 400

    # 处理选项字段
    options = None
    if field_type in ['select', 'radio', 'checkbox'] and data.get('options'):
        if isinstance(data['options'], list):
            options = json.dumps(data['options'])
        else:
            return jsonify({'error': '选项必须是数组格式'}), 400

    field = WorkOrderField(
        name=data['name'],
        label=label,
        field_type=field_type,
        options=options,
        is_required=data.get('is_required', False),
        default_value=data.get('default_value'),
        placeholder=data.get('placeholder'),
        sort_order=data.get('sort_order', 0),
        is_active=data.get('is_active', True),
        field_category=data.get('field_category', 'custom'),
        is_visible=data.get('is_visible', True),
        system_required=data.get('system_required', False),
        description=data.get('description')
    )

    db.session.add(field)
    db.session.commit()

    return jsonify({
        'field': field.to_dict(),
        'message': '字段创建成功'
    }), 201

@work_orders_fields_bp.route('/fields/<int:field_id>', methods=['PUT'])
@jwt_required()
@require_permission('work_order.field_manage')
@handle_db_error("更新工单字段")
def update_work_order_field(field_id):
    """更新工单自定义字段"""
    field = WorkOrderField.query.get_or_404(field_id)
    data = request.get_json()

    if not data:
        return jsonify({'error': '未收到请求数据'}), 400

    # 检查字段名是否已被其他字段使用
    if 'name' in data and data['name'] != field.name:
        if WorkOrderField.query.filter_by(name=data['name']).first():
            return jsonify({'error': '字段名称已存在'}), 400

    # 验证字段类型
    if 'field_type' in data:
        valid_types = ['text', 'textarea', 'number', 'date', 'datetime', 'select', 'radio', 'checkbox', 'file']
        if data['field_type'] not in valid_types:
            return jsonify({'error': f'无效的字段类型，支持的类型：{valid_types}'}), 400

    # 更新字段
    updatable_fields = ['name', 'field_type', 'is_required', 'default_value', 'placeholder', 'sort_order', 'is_active', 'field_category', 'is_visible', 'system_required', 'description']
    for attr in updatable_fields:
        if attr in data:
            setattr(field, attr, data[attr])

    # 处理label字段
    if 'label' in data:
        field.label = data['label']
    elif 'name' in data:
        # 如果更新了name但没有提供label，使用新的name作为label
        field.label = data['name']

    # 确保label不为空
    if not field.label:
        field.label = field.name or '未命名字段'

    # 处理选项字段
    if 'options' in data:
        if data['options'] is None or (isinstance(data['options'], list) and len(data['options']) == 0):
            field.options = None
        elif isinstance(data['options'], list):
            field.options = json.dumps(data['options'])
        else:
            return jsonify({'error': '选项必须是数组格式'}), 400

    db.session.commit()

    return jsonify({
        'field': field.to_dict(),
        'message': '字段更新成功'
    }), 200

@work_orders_fields_bp.route('/fields/<int:field_id>', methods=['DELETE'])
@jwt_required()
@require_permission('work_order.field_manage')
@handle_db_error("删除工单字段")
def delete_work_order_field(field_id):
    """删除工单字段（仅限自定义字段）"""
    field = WorkOrderField.query.get_or_404(field_id)

    # 检查是否为基础字段
    if field.field_category == 'basic':
        return jsonify({
            'error': '基础字段不能删除'
        }), 400

    # 检查是否有工单使用了这个字段
    field_values_count = WorkOrderFieldValue.query.filter_by(field_id=field.id).count()
    if field_values_count > 0:
        return jsonify({
            'error': f'无法删除字段，有 {field_values_count} 个工单正在使用此字段'
        }), 400

    # 删除字段
    db.session.delete(field)
    db.session.commit()

    return jsonify({'message': '字段删除成功'}), 200

@work_orders_fields_bp.route('/fields/<int:field_id>/toggle', methods=['PUT'])
@jwt_required()
@require_permission('work_order.field_manage')
@handle_db_error("切换字段状态")
def toggle_field_status(field_id):
    """切换字段启用/禁用状态"""
    field = WorkOrderField.query.get_or_404(field_id)
    
    field.is_active = not field.is_active
    db.session.commit()
    
    status = '启用' if field.is_active else '禁用'
    return jsonify({
        'field': field.to_dict(),
        'message': f'字段已{status}'
    }), 200

@work_orders_fields_bp.route('/fields/reorder', methods=['PUT'])
@jwt_required()
@require_permission('work_order.field_manage')
@handle_db_error("重新排序字段")
def reorder_fields():
    """重新排序字段"""
    data = request.get_json()
    
    if not data or 'field_orders' not in data:
        return jsonify({'error': '缺少字段排序数据'}), 400
    
    field_orders = data['field_orders']
    if not isinstance(field_orders, list):
        return jsonify({'error': '字段排序数据格式错误'}), 400
    
    # 更新字段排序
    for order_data in field_orders:
        field_id = order_data.get('field_id')
        sort_order = order_data.get('sort_order')
        
        if field_id is not None and sort_order is not None:
            field = WorkOrderField.query.get(field_id)
            if field:
                field.sort_order = sort_order
    
    db.session.commit()
    
    return jsonify({'message': '字段排序更新成功'}), 200

@work_orders_fields_bp.route('/fields/validate', methods=['POST'])
@jwt_required()
@require_permission('work_order.view')
def validate_field_values():
    """验证字段值"""
    try:
        data = request.get_json()
        
        if not data or 'field_values' not in data:
            return jsonify({'error': '缺少字段值数据'}), 400
        
        field_values = data['field_values']
        errors = []
        
        # 获取所有字段定义
        fields = WorkOrderField.query.filter_by(is_active=True).all()
        field_dict = {field.name: field for field in fields}
        
        # 验证每个字段值
        for field_name, field_value in field_values.items():
            field_def = field_dict.get(field_name)
            if not field_def:
                continue
            
            # 检查必填字段
            if field_def.is_required and (field_value is None or field_value == ''):
                errors.append(f'字段 {field_def.label} 是必填项')
                continue
            
            # 跳过空值的其他验证
            if field_value is None or field_value == '':
                continue
            
            # 类型验证
            if field_def.field_type == 'number':
                try:
                    float(field_value)
                except (ValueError, TypeError):
                    errors.append(f'字段 {field_def.label} 必须是数字')
            
            elif field_def.field_type in ['select', 'radio']:
                if field_def.options:
                    try:
                        valid_options = json.loads(field_def.options)
                        if field_value not in valid_options:
                            errors.append(f'字段 {field_def.label} 的值不在有效选项中')
                    except json.JSONDecodeError:
                        pass
            
            elif field_def.field_type == 'checkbox':
                if field_def.options:
                    try:
                        valid_options = json.loads(field_def.options)
                        if isinstance(field_value, list):
                            for value in field_value:
                                if value not in valid_options:
                                    errors.append(f'字段 {field_def.label} 包含无效选项：{value}')
                        else:
                            errors.append(f'字段 {field_def.label} 必须是数组格式')
                    except json.JSONDecodeError:
                        pass
        
        if errors:
            return jsonify({
                'valid': False,
                'errors': errors
            }), 400
        
        return jsonify({
            'valid': True,
            'message': '字段值验证通过'
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@work_orders_fields_bp.route('/fields/basic/batch-update', methods=['PUT'])
@jwt_required()
@require_permission('work_order.field_manage')
@handle_db_error("批量更新基础字段配置")
def batch_update_basic_fields():
    """批量更新基础字段配置"""
    data = request.get_json()
    
    if not data or 'fields' not in data:
        return jsonify({'error': '缺少字段配置数据'}), 400
    
    fields_data = data['fields']
    if not isinstance(fields_data, list):
        return jsonify({'error': '字段配置数据格式错误'}), 400
    
    updated_fields = []
    
    for field_data in fields_data:
        field_name = field_data.get('name')
        if not field_name:
            continue
        
        # 查找基础字段
        field = WorkOrderField.query.filter_by(
            name=field_name, 
            field_category='basic'
        ).first()
        
        if not field:
            continue
        
        # 更新允许修改的字段
        updatable_attrs = ['is_visible', 'is_required', 'sort_order', 'description', 'options']
        
        # 系统必需字段不允许修改 is_required
        if field.system_required and 'is_required' in field_data:
            continue
        
        for attr in updatable_attrs:
            if attr in field_data:
                setattr(field, attr, field_data[attr])
        
        updated_fields.append(field.to_dict())
    
    db.session.commit()
    
    return jsonify({
        'fields': updated_fields,
        'message': f'成功更新 {len(updated_fields)} 个基础字段配置'
    }), 200